import datetime
from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from sqlalchemy import desc, or_
from app.models import AdminLog, Admin
from app.core.extensions import db
from . import admin_blueprint
from app.services.decorators import admin_required


@admin_blueprint.route('/logs', methods=['GET'])
@jwt_required()
@admin_required
def get_logs():
    """获取管理员日志列表
    
    查询参数:
    - page: 页码，默认1
    - per_page: 每页数量，默认20
    - search: 搜索关键词（操作内容）
    - admin_id: 管理员ID
    - action: 操作类型
    - start_date: 开始日期（格式：YYYY-MM-DD）
    - end_date: 结束日期（格式：YYYY-MM-DD）
    """
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    search = request.args.get('search', '')
    admin_id = request.args.get('admin_id', '')
    action = request.args.get('action', '')
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')

    # 构建查询
    query = AdminLog.query

    # 根据管理员ID筛选
    if admin_id:
        try:
            admin_id = int(admin_id)
            query = query.filter(AdminLog.admin_id == admin_id)
        except (ValueError, TypeError):
            return jsonify({'code': 1, 'message': '管理员ID必须是数字'}), 400

    # 根据操作类型筛选
    if action:
        query = query.filter(AdminLog.action == action)

    # 根据日期范围筛选
    if start_date:
        try:
            start_datetime = datetime.datetime.strptime(start_date, '%Y-%m-%d')
            query = query.filter(AdminLog.create_time >= start_datetime)
        except ValueError:
            return jsonify({'code': 1, 'message': '开始日期格式不正确'}), 400

    if end_date:
        try:
            end_datetime = datetime.datetime.strptime(end_date, '%Y-%m-%d')
            # 将结束日期设置为当天的23:59:59
            end_datetime = end_datetime.replace(hour=23, minute=59, second=59)
            query = query.filter(AdminLog.create_time <= end_datetime)
        except ValueError:
            return jsonify({'code': 1, 'message': '结束日期格式不正确'}), 400

    # 关键词搜索
    if search:
        query = query.filter(
            or_(
                AdminLog.action.like(f'%{search}%'),
                AdminLog.details.like(f'%{search}%'),
                AdminLog.ip.like(f'%{search}%')
            )
        )

    # 执行分页查询
    pagination = query.order_by(desc(AdminLog.create_time)).paginate(
        page=page, per_page=per_page, error_out=False
    )

    logs = pagination.items

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': pagination.total,
            'pages': pagination.pages,
            'page': page,
            'per_page': per_page,
            'items': [log_to_dict(log) for log in logs]
        }
    }

    return jsonify(result)


@admin_blueprint.route('/logs/actions', methods=['GET'])
@jwt_required()
def get_log_actions():
    """获取日志操作类型列表"""
    # 查询所有不重复的操作类型
    actions = db.session.query(AdminLog.action).distinct().all()

    # 提取操作类型
    action_list = [action[0] for action in actions]

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': action_list
    })


@admin_blueprint.route('/logs/admins', methods=['GET'])
@jwt_required()
def get_log_admins():
    """获取有日志记录的管理员列表"""
    # 查询所有有日志记录的管理员ID
    admin_ids = db.session.query(AdminLog.admin_id).distinct().filter(AdminLog.admin_id.isnot(None)).all()

    # 提取管理员ID
    admin_id_list = [admin_id[0] for admin_id in admin_ids]

    # 查询管理员信息
    admins = Admin.query.filter(Admin.id.in_(admin_id_list)).all()

    # 构建管理员列表
    admin_list = [{
        'id': admin.id,
        'username': admin.username
    } for admin in admins]

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': admin_list
    })


@admin_blueprint.route('/logs/statistics', methods=['GET'])
@jwt_required()
@admin_required
def get_log_statistics():
    """获取日志统计数据"""
    # 获取时间范围参数
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')

    start_datetime = None
    end_datetime = None

    # 如果没有指定时间范围，默认查询最近7天
    if not start_date:
        start_datetime = datetime.datetime.now() - datetime.timedelta(days=7)
    else:
        try:
            start_datetime = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        except ValueError:
            return jsonify({'code': 1, 'message': '开始日期格式不正确'}), 400

    if not end_date:
        end_datetime = datetime.datetime.now()
    else:
        try:
            end_datetime = datetime.datetime.strptime(end_date, '%Y-%m-%d')
            # 将结束日期设置为当天的23:59:59
            end_datetime = end_datetime.replace(hour=23, minute=59, second=59)
        except ValueError:
            return jsonify({'code': 1, 'message': '结束日期格式不正确'}), 400

    # 统计每天的日志数量
    daily_stats = []
    current_date = start_datetime.date()
    end_date = end_datetime.date()

    while current_date <= end_date:
        day_start = datetime.datetime.combine(current_date, datetime.time.min)
        day_end = datetime.datetime.combine(current_date, datetime.time.max)

        # 统计当天日志数
        day_logs = AdminLog.query.filter(
            AdminLog.create_time >= day_start,
            AdminLog.create_time <= day_end
        ).count()

        daily_stats.append({
            'date': current_date.strftime('%Y-%m-%d'),
            'count': day_logs
        })

        current_date += datetime.timedelta(days=1)

    # 统计操作类型分布
    action_stats = db.session.query(
        AdminLog.action, db.func.count(AdminLog.id)
    ).filter(
        AdminLog.create_time >= start_datetime,
        AdminLog.create_time <= end_datetime
    ).group_by(AdminLog.action).all()

    action_distribution = [{
        'action': action,
        'count': count
    } for action, count in action_stats]

    # 统计管理员操作次数
    admin_stats = db.session.query(
        AdminLog.admin_id, db.func.count(AdminLog.id)
    ).filter(
        AdminLog.create_time >= start_datetime,
        AdminLog.create_time <= end_datetime,
        AdminLog.admin_id.isnot(None)
    ).group_by(AdminLog.admin_id).all()

    admin_distribution = []
    for admin_id, count in admin_stats:
        admin = Admin.query.get(admin_id)
        if admin:
            admin_distribution.append({
                'admin_id': admin_id,
                'username': admin.username,
                'count': count
            })

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': {
            'daily_stats': daily_stats,
            'action_distribution': action_distribution,
            'admin_distribution': admin_distribution
        }
    })


@admin_blueprint.route('/logs/clear', methods=['POST'])
@jwt_required()
@admin_required
def clear_logs():
    """清空日志（仅供超级管理员使用）"""
    # 获取当前管理员

    # 验证是否为超级管理员
    admin = Admin.query.get(get_jwt_identity())
    if not admin or not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员才能清空日志'}), 403

    # 获取日期参数
    data = request.json
    before_date = data.get('before_date', '')

    if before_date:
        try:
            before_datetime = datetime.datetime.strptime(before_date, '%Y-%m-%d')
            # 将日期设置为当天的23:59:59
            before_datetime = before_datetime.replace(hour=23, minute=59, second=59)

            # 删除指定日期之前的日志
            db.session.query(AdminLog).filter(AdminLog.create_time <= before_datetime).delete()
        except ValueError:
            return jsonify({'code': 1, 'message': '日期格式不正确'}), 400
    else:
        # 如果没有指定日期，则清空所有日志
        db.session.query(AdminLog).delete()

    # 记录清空日志的操作
    log = AdminLog(
        admin_id=admin_id,
        action='清空日志',
        ip=request.remote_addr,
        details=f'清空{"指定日期前" if before_date else "所有"}的日志'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '日志清空成功'
    })


def log_to_dict(log):
    """将日志对象转换为字典"""
    # 获取管理员信息
    admin = Admin.query.get(log.admin_id) if log.admin_id else None

    return {
        'id': log.id,
        'admin_id': log.admin_id,
        'action': log.action,
        'details': log.details,
        'ip': log.ip,
        'create_time': log.create_time.strftime('%Y-%m-%d %H:%M:%S') if log.create_time else None,
        'admin': {
            'username': admin.username
        } if admin else None
    }
